/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sirtet.tetris;

import java.io.File;
import javax.swing.JFileChooser;
import sirtet.GameAction;
import sirtet.GameBoard;
import sirtet.event.BoardActionEvent;
import sirtet.event.BoardBlocksEliminatedEvent;
import sirtet.event.BoardEvent;
import sirtet.event.BoardListener;
import sirtet.event.BoardPieceEvent;
import sirtet.event.BoardPieceFixedEvent;
import sirtet.netplay.NetworkPlayer;
import sirtet.netplay.ServerResponse;
import sirtet.netplay.server.GameRoom;
import sirtet.tetris.gui.TetrisFrame;

/**
 * A GameRoom for Battling Super Tetris
 * @author guangwei.zhu
 */
public class TetrisQualifierRoom extends GameRoom {

    public static int BOARD_WIDTH = 20;
    public static int BOARD_HEIGHT = 30;
    private BoardListener gameoverHandler = new BoardListener() {

        private int linesEliminated = 0;

        public void boardChanged(BoardEvent evt) {
        }

        public void boardDisposing(BoardEvent evt) {
        }

        public synchronized void boardGameOver(BoardEvent evt) {

            GameBoard board = (GameBoard) evt.getSource();
            GameAction action = new GameAction();

            for (NetworkPlayer player : getPlayers()) {
                // Only one player actually
                action.actor = player.id();
                System.out.println("****Final Eliminated Lines: " + linesEliminated);
                action.command = ServerResponse.GAMEOVER;   // Tell client to stop
                broadcast(action);
                if (linesEliminated > 20) {
                    action.command = ServerResponse.WIN;
                } else {
                    action.command = ServerResponse.LOSE;
                }

                broadcast(action);
            }
            // TODO check Concurrent
            // board.dispose();
        }

        public void boardStarted(BoardEvent evt) {
            linesEliminated = 0;
        }

        public void boardReset(BoardEvent evt) {
            linesEliminated = 0;
        }

        public void boardPieceFixed(BoardPieceFixedEvent evt) {
        }

        public void boardNextPieceChanged(BoardPieceEvent evt) {
        }

        @SuppressWarnings("unchecked")
        public void boardBlocksEliminated(BoardBlocksEliminatedEvent evt) {
            linesEliminated += ((Object[]) evt.eliminatedBlocks).length;
        }

        public void boardActionTriggered(BoardActionEvent evt) {
        }
    };

    protected class QualifierTetrisBoard extends TetrisBoard {

        public QualifierTetrisBoard(int width, int height) {
            super(width, height);
        }

        @Override
        protected void afterNextPiece() {
            if (pieceProvider.remaining() > 0) {
                super.afterNextPiece();
            } else {
                gameover();
                return;
            }
        }
    }

    public TetrisQualifierRoom() {
        super.setMaxBoards(1);
        super.setMinBoards(1);
        super.setMaxPlayers(1);
        super.setMinPlayers(1);
    }

    @Override
    protected void playerQuit(NetworkPlayer player) {
        GameBoard oldboard = (GameBoard) seatTable.get(player);
        super.playerQuit(player);
        if (oldboard != null) {
            // TODO check Concurrent
            // oldboard.dispose();
        }
    }

    @Override
    protected GameBoard createBoard(NetworkPlayer player) {
        TetrisBoard newBoard = new QualifierTetrisBoard(BOARD_WIDTH, BOARD_HEIGHT);
        JFileChooser fileChooser = new JFileChooser();

        fileChooser.setDialogTitle("Select piece file for player " + player.id());
        int ret = fileChooser.showSaveDialog(null);
        if (ret == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            // Add remote piece provider
            try {
                newBoard.setPieceProvider(new SynchronousPieceProvider(new FilePieceProvider(file), player));
            } catch (Exception ex) {
            }
        } else {
            newBoard.setPieceProvider(new SynchronousPieceProvider(new RandomPieceProvider(), player));
        }

        // Add fall enforcer
        newBoard.registerPlayer(new FallEnforcer(player.id(), 500));

        // Add gameover listener
        newBoard.addBoardListener(gameoverHandler);

        new TetrisFrame(newBoard, player).setVisible(true);

        return newBoard;
    }

    @Override
    public void setMaxBoards(int maxBoards) {
        if (maxBoards != 1) {
            throw new IllegalArgumentException("Qualifier room allows only one player.");
        }
    }

    @Override
    public void setMaxPlayers(int maxPlayers) {
        if (maxPlayers != 1) {
            throw new IllegalArgumentException("Qualifier room allows only one player.");
        }
    }
}
